import { getLogger } from '@dui/node-logger';
import { HttpException, Injectable } from '@nestjs/common';
import httpClient from '~/common/client/http.client';
import { createEnvPath, createIndexUrl, createVersionIndexUrl, createVersionPath, getShortEnv, isFullUrl, isMicrofe, joinImportmap, joinMicrofeUrlPath, joinUrlPath, joinVersionImportmap } from '~/utils';
import cheerio from 'cheerio';
import config from 'config';

interface CacheItem {
  etag: string;
  html: string;
}

@Injectable()
export class AppService {
  private cache: { [url: string]: CacheItem | undefined } = {};
  // 请求存放在oss中的html，如果返回200，处理后的结果加入缓存中，否则使用缓存
  async fetchIndexHtml(cdnRoot: string): Promise<string> {
    let ossUrl = createVersionIndexUrl(cdnRoot);
    let isOldPath = false;
    const cacheItem = this.cache[ossUrl];
    // 如果文件没变，使用缓存
    let { headers, result, statusCode } = await httpClient.get<string, Error>(
      ossUrl,
      {
        headers: {
          'if-none-match': cacheItem && cacheItem.etag,
        },
      },
    );
    // if (statusCode === 404) {
    //   // 未找到 `www/版本/path下` 相关html，再找 `www/path/环境下` index.html
    //   isOldPath = true;
    //   ossUrl = createIndexUrl(cdnRoot);
    //   const response = await httpClient.get<string, Error>(ossUrl);
    //   headers = response.headers;
    //   result = response.result;
    //   statusCode = response.statusCode;
    // }
    const logger = getLogger();
    if (statusCode === 200) {
      const finalHtml = this.htmlPostProcess(
        result,
        cdnRoot,
        getShortEnv(),
        isOldPath,
      );
      const etag = headers['etag'] as string;
      this.cache[ossUrl] = {
        etag,
        html: finalHtml,
      };
      logger.info(
        'GET %s %d ，etag 为 %s，更新缓存 \n%s',
        ossUrl,
        statusCode,
        etag,
        finalHtml,
      );
    } else if (statusCode === 304) {
      logger.info(
        'GET %s %d etag 为 %s，文件无变化，使用缓存',
        ossUrl,
        statusCode,
        cacheItem.etag,
      );
    } else {
      logger.warn('GET %s %d ，降级使用缓存', ossUrl, statusCode);
      if (!this.cache[ossUrl]) {
        logger.error(
          'GET %s %d ，请求失败，并且无缓存可用',
          ossUrl,
          statusCode,
        );
        throw new HttpException(`不能正常获取页面 ${cdnRoot}`, 404);
      }
    }

    return this.cache[ossUrl].html;
  }

  htmlPostProcess(html: string, cdnRoot: string, env: string, isOld: boolean) {
    const $ = cheerio.load(html);
    const cdn = config.get('OSS_BASE_URL') as string;
    let baseUrl = isOld
      ? joinUrlPath(cdn, cdnRoot, env, '/')
      : joinUrlPath(cdn, createVersionPath(cdnRoot), '/');
    // const Microfe = isMicrofe(cdnRoot);
    // if (Microfe) {
    //   baseUrl = isOld
    //     ? joinMicrofeUrlPath(cdn, cdnRoot, env)
    //     : joinUrlPath(cdn, createVersionPath(cdnRoot), '/');
    // }
    // const envPath = joinUrlPath(cdn, createEnvPath());
    $('link').each((index, ele: any) => {
      let href = ele.attribs['href'];
      if (href && !isFullUrl(href)) {
        href = joinUrlPath(baseUrl, href);
        ele.attribs['href'] = href;
      }
    });

    $('script').each((index, ele: any) => {
      let src = ele.attribs['src'];
      if (src && !isFullUrl(src)) {
        src = joinUrlPath(baseUrl, src);
        ele.attribs['src'] = src;
      }
      // const type = ele.attribs['type'];
      // if (Microfe && type === 'systemjs-importmap') {
      //   // 修改importmap配置中的路径
      //   const script = ele.children[0];
      //   const text = script.data;
      //   try {
      //     const maps = JSON.parse(text);
      //     for (const key in maps.imports) {
      //       if (maps.imports[key] && !isFullUrl(maps.imports[key])) {
      //         maps.imports[key] = joinUrlPath(baseUrl, maps.imports[key]);
      //       }
      //     }
      //     script.data = JSON.stringify(maps);
      //   } catch (e) {
      //     console.log(e);
      //   }
      // }
    });

    $('head').append(`<script>window.__PUBLIC_PATH="${baseUrl}"</script>`);
    // $('head').append(
    //   `<script type="text/javascript" src="https://mstatic.cassmall.com/assets/sensors/cassSensors.js"></script>`,
    // );
    if (env === 'alpha') {
      // $('head').append(
      //   `<script type="text/javascript" src="https://mstatic.cassmall.com/assets/apm-web/web-report-default.min.js"></script>`,
      // );
      // $('head').append(
      //   `<script>
      //   Performance({
      //       domain: 'https://apm-alpha.casstime.com/api/v1/report/web',
      //       add:{
      //         appId:'pzw4HAJ1633747921324'
      //       }
      //   })
      //   </script>`,
      // );
    }

    // const mallProjectCdnRoots = [
    //   'www/mall/vip',
    //   'www/mall/order',
    //   'www/cassmall/inquiry',
    //   'www/mall/market/product',
    //   'www/mall/activity/product',
    //   'www/cassmall/finance',
    //   'www/cassmall/help-center',
    // ];

    // if (mallProjectCdnRoots.includes(cdnRoot)) {
    //   $('body').append(
    //     `<script type="text/javascript" src="https://mstatic.cassmall.com/assets/chrome-download-guide/guide.js"></script>`,
    //   );
    // }

    // if (Microfe) {
    //   // 添加importmap路径
    //   const importmapPath = isOld
    //     ? joinImportmap(cdn, cdnRoot, env)
    //     : joinVersionImportmap(cdn, cdnRoot);
    //   $('head').append(
    //     `<script>window.__IMPORTMAP_PATH="${importmapPath}";</script>`,
    //   );
    //   $('head').append(`<script>window.__ENV_PATH="${envPath}"</script>`);
    // }
    return $.html();
  }
}
